diff options
| author | Paul Buetow <paul@buetow.org> | 2010-05-09 09:30:29 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2010-05-09 09:30:29 +0000 |
| commit | a90467d4be3bcf91cab299b4521bf5f762abb1d5 (patch) | |
| tree | 5171d406e6be467807a914ce42923ac997d74858 /src/data | |
added the scheme branch
Diffstat (limited to 'src/data')
| -rw-r--r-- | src/data/array.c | 327 | ||||
| -rw-r--r-- | src/data/array.h | 94 | ||||
| -rw-r--r-- | src/data/cons.c | 88 | ||||
| -rw-r--r-- | src/data/cons.h | 55 | ||||
| -rw-r--r-- | src/data/dat.c | 268 | ||||
| -rw-r--r-- | src/data/dat.h | 88 | ||||
| -rw-r--r-- | src/data/hash.c | 306 | ||||
| -rw-r--r-- | src/data/hash.h | 84 | ||||
| -rw-r--r-- | src/data/list.c | 531 | ||||
| -rw-r--r-- | src/data/list.h | 118 | ||||
| -rw-r--r-- | src/data/map.c | 289 | ||||
| -rw-r--r-- | src/data/map.h | 88 | ||||
| -rw-r--r-- | src/data/queue.c | 210 | ||||
| -rw-r--r-- | src/data/queue.h | 81 | ||||
| -rw-r--r-- | src/data/stack.c | 271 | ||||
| -rw-r--r-- | src/data/stack.h | 79 | ||||
| -rw-r--r-- | src/data/tree.c | 215 | ||||
| -rw-r--r-- | src/data/tree.h | 106 | ||||
| -rw-r--r-- | src/data/tupel.c | 53 | ||||
| -rw-r--r-- | src/data/tupel.h | 47 | ||||
| -rw-r--r-- | src/data/types.h | 64 |
21 files changed, 3462 insertions, 0 deletions
diff --git a/src/data/array.c b/src/data/array.c new file mode 100644 index 0000000..f50e998 --- /dev/null +++ b/src/data/array.c @@ -0,0 +1,327 @@ +/*:* + *: File: ./src/data/array.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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; + array_set_used(p_array, 0); + + return (p_array); +} + +Array* +array_new_size(int i_size) { + Array *p_array = array_new(); + + array_resize(p_array, i_size); + + return (p_array); +} + +void +_unshift_cb(void *p_array, void *p_void) { + array_unshift(p_array, p_void); +} + +Array* +array_new_copy(Array *p_array) { + Array *p_array_cpy = array_new_size(array_get_size(p_array)); + array_iterate2(p_array, _unshift_cb, p_array_cpy); + + return (p_array_cpy); +} + +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_delete_iterate(Array *p_array, void (*func)(void *)) { + if (!p_array) + return; + + array_iterate(p_array, func); + + 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; + } + + if (p_array->i_used < i_index) + array_set_used(p_array, i_index); +} + +void +array_set_used(Array *p_array, int i_used) { + p_array->i_used = i_used; +} + + +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; + } + + if (p_array->i_used < i_index) + array_set_used(p_array, i_index); +} + +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; + if (p_array->i_used > i_size) + array_set_used(p_array, 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_used = array_get_used(p_array); + array_set(p_array, i_used, p_void); + array_set_used(p_array, 1+i_used); +} + +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_append(Array *p_array, Array *p_array_append) { + int i_size = array_get_size(p_array) + array_get_size(p_array_append); + array_resize(p_array, i_size); + array_iterate2(p_array_append, _unshift_cb, p_array); +} + +void +array_iterate(Array *p_array, void (*func)(void *)) { + if (!p_array) + return; + + for (int i = 0; i < array_get_used(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_used(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) { + //printf("[%d]", p_arrayiterator->p_array->i_used); + return (p_arrayiterator->i_cur_pos < + array_get_used(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..6800061 --- /dev/null +++ b/src/data/array.h @@ -0,0 +1,94 @@ +/*:* + *: File: ./src/data/array.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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_get_used(a) a->i_used +#define array_get_ind(a) (a->i_used - 1) +#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_used; + int i_size; +} Array; + +typedef struct { + Array *p_array; + int i_cur_pos; +} ArrayIterator; + +Array *array_new(); +Array *array_new_size(int i_size); +Array *array_new_copy(Array *p_array); +void array_delete(Array *p_array); +void array_delete_iterate(Array *p_array, void (*func)(void*)); +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_append(Array *p_array, Array *p_array_append); +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); +void array_set_used(Array *p_array, int i_used); + +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/cons.c b/src/data/cons.c new file mode 100644 index 0000000..7331167 --- /dev/null +++ b/src/data/cons.c @@ -0,0 +1,88 @@ +/*:* + *: File: ./src/data/cons.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "cons.h" + +Cons* +cons_new(void *p_val) { + Cons *p_cons = malloc(sizeof(Cons)); + + p_cons->p_val = p_val; + p_cons->p_succ = NULL; + + return (p_cons); +} + +void +cons_delete(Cons *p_cons) { + free(p_cons); +} + +void +cons_delete_cb(void *p_cons) { + cons_delete(p_cons); +} + +void +cons_iterate(Cons *p_cons, void (*func)(void *)) { + if (p_cons != NULL && p_cons->p_val != NULL) { + (*func) (p_cons->p_val); + cons_iterate(p_cons->p_succ, func); + } +} + +void* +cons_car(Cons *p_cons) { + return (p_cons->p_val); +} + +Cons* +cons_cdr(Cons *p_cons) { + return (p_cons->p_succ); +} + +Cons* +cons_cons(Cons *p_cons, void *p_val) { + if (p_cons->p_val == NULL) { + p_cons->p_val = p_val; + return (p_cons); + + } else if (p_val == NULL) { + return (p_cons); + } + + Cons *p_new = cons_new(p_val); + p_new->p_succ = p_cons; + return (p_new); +} diff --git a/src/data/cons.h b/src/data/cons.h new file mode 100644 index 0000000..130415b --- /dev/null +++ b/src/data/cons.h @@ -0,0 +1,55 @@ +/*:* + *: File: ./src/data/cons.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 CONS_H +#define CONS_H + +#include <stdlib.h> + +#include "../defines.h" + +typedef struct Cons_ { + void *p_val; + struct Cons_ *p_succ; +} Cons; + +Cons *cons_new(void *p_val); +void cons_delete(Cons *p_cons); +void cons_delete_cb(void *p_cons); +void cons_iterate(Cons *p_cons, void (*func)(void *)); +void *cons_car(Cons *p_cons); +Cons *cons_cdr(Cons *p_cons); +Cons *cons_cons(Cons *p_cons, void *p_val); + +#endif diff --git a/src/data/dat.c b/src/data/dat.c new file mode 100644 index 0000000..b448cdc --- /dev/null +++ b/src/data/dat.c @@ -0,0 +1,268 @@ +/*:* + *: File: ./src/data/dat.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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> +#include "../defines.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 (false); + + 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 (NULL); + + 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..dcc7928 --- /dev/null +++ b/src/data/dat.h @@ -0,0 +1,88 @@ +/*:* + *: File: ./src/data/dat.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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..e196840 --- /dev/null +++ b/src/data/hash.c @@ -0,0 +1,306 @@ +/*:* + *: File: ./src/data/hash.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 (NULL); + + 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 (NULL); + + *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); +} + +void +hash_iterate_key(Hash *p_hash, void (*func)(void *, char *)) { + 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, p_hash->p_elems[i].c_key); +} + +_Bool +hash_key_exists(Hash *p_hash, char *c_key) { + if (hash_get(p_hash, c_key)) + return (true); + + return (false); +} diff --git a/src/data/hash.h b/src/data/hash.h new file mode 100644 index 0000000..8bf0a49 --- /dev/null +++ b/src/data/hash.h @@ -0,0 +1,84 @@ +/*:* + *: File: ./src/data/hash.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 HASH_H +#define HASH_H + +#include "../defines.h" +#include "types.h" + +typedef enum HASH_OP_ { + FREE_ADDR, + OCC_ADDR +} HASH_OP; + +typedef struct { + char c_key[HASH_MKEYLEN]; + char flag; + TYPE type; + void *p_val; +} HashElem; + +typedef struct { + HashElem *p_elems; + unsigned i_size; + unsigned i_cur_size; +} Hash; + +Hash*hash_new(unsigned i_size); +void hash_delete(Hash *p_hash); +RETCODE hash_insert(Hash *p_hash, char *c_key, void *p_val); +RETCODE hash_insert_ht(Hash *p_hash, char *c_key, void *p_val, TYPE type); +void* hash_get(Hash *p_hash, char *c_key); +void* hash_get_ht(Hash *p_hash, char *c_key, TYPE *p_type); +void* hash_get_ht_addr(Hash *p_hash, char *c_key, TYPE *p_type, int *p_addr); +void* hash_remove(Hash *p_hash, char *c_key); +void hash_print(Hash *p_hash); +void hash_print_addrval(Hash *p_hash, int i_addr); +RETCODE hash_size(Hash *p_hash, int i_size); + +int hash_getaddr(Hash *p_hash, char *c_key, HASH_OP OP); +RETCODE hash_addrisfree(Hash *p_hash, int i_addr); +RETCODE hash_addrisocc(Hash *p_hash, int i_addr, char *c_key); +int hash_nextaddr(Hash *p_hash, int i_max_tries, + char *c_key, int i_addr, + HASH_OP OP); +void hash_iterate(Hash *p_hash, void (*func)(void *)); +void hash_iterate_key(Hash *p_hash, void (*func)(void *, char *)); +_Bool hash_key_exists(Hash *p_hash, char *c_key); + +#define hash_get_cur_size(hash) hash->i_cur_size +#define hash_get_size(hash) hash->i_size + +#endif diff --git a/src/data/list.c b/src/data/list.c new file mode 100644 index 0000000..e641133 --- /dev/null +++ b/src/data/list.c @@ -0,0 +1,531 @@ +/*:* + *: File: ./src/data/list.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "list.h" + +List* +list_new() { + List *p_list = malloc(sizeof(List)); + + p_list->p_first = NULL; + p_list->p_last = NULL; + p_list->i_size = 0; + + return (p_list); +} + +void +_list_copy_cb(void *p_void1, void *p_cpy) { + ListElem *p_elem = p_void1; + list_add_back(p_cpy, p_elem->p_val); +} + +List* +list_copy(List *p_list) { + List *p_list_cpy = list_new(); + list_iterate2(p_list, _list_copy_cb, p_list_cpy); + return (p_list_cpy); +} + +List* +list_copy2(List *p_list, void* (*func)(void *)) { + List *p_list_cpy = list_new(); + ListIterator *p_iter = listiterator_new(p_list); + + while (listiterator_has_next(p_iter)) + list_add_back(p_list_cpy, (*func) (listiterator_next(p_iter))); + + listiterator_delete(p_iter); + + return (p_list_cpy); +} + +ListElem* +listelem_new() { + ListElem *p_elem = malloc(sizeof(ListElem)); + + p_elem->p_next = NULL; + p_elem->p_prev = NULL; + p_elem->p_val = NULL; + + return (p_elem); +} + +_Bool +list_empty(List *p_list) { + return (p_list->i_size == 0); +} + +void +list_concat_front(List *p_list1, List *p_list2) { + if (!p_list1 || !p_list2 || !p_list2->p_last) + return; + + ListElem *p_first = p_list1->p_first; + + if (!p_first) { + p_list1->p_first = p_list2->p_first; + p_list1->p_last = p_list2->p_last; + + } else { + p_list2->p_last->p_next = p_list1->p_first; + p_list1->p_first->p_prev = p_list2->p_last; + p_list1->p_first = p_list2->p_first; + } + + p_list1->i_size += p_list2->i_size; + p_list2->i_size = 0; + p_list2->p_first = NULL; + p_list2->p_last = NULL; +} + +void +list_concat_back(List *p_list1, List *p_list2) { + if (!p_list1 || !p_list2 || !p_list2->p_first) + return; + + ListElem *p_last = p_list1->p_last; + + if (!p_last) { + p_list1->p_first = p_list2->p_first; + p_list1->p_last = p_list2->p_last; + + } else { + p_last->p_next = p_list2->p_first; + p_list2->p_first->p_prev = p_last; + p_list1->p_last = p_list2->p_last; + } + + p_list1->i_size += p_list2->i_size; + p_list2->i_size = 0; + p_list2->p_first = NULL; + p_list2->p_last = NULL; + +} + +void +list_add_front(List *p_list, void *p_val) { + ListElem *p_elem = listelem_new(); + + p_elem->p_val = p_val; + if (p_list->p_first == NULL) { + p_list->p_first = p_elem; + p_list->p_last = p_elem; + + } else { + p_elem->p_next = p_list->p_first; + p_list->p_first->p_prev = p_elem; + p_list->p_first = p_elem; + } + + ++p_list->i_size; +} + +void +list_add_back(List *p_list, void *p_val) { + ListElem *p_elem = listelem_new(); + + p_elem->p_val = p_val; + if (p_list->p_last == NULL) { + p_list->p_first = p_elem; + p_list->p_last = p_elem; + + } else { + p_elem->p_prev = p_list->p_last; + p_list->p_last->p_next = p_elem; + p_list->p_last = p_elem; + } + + ++p_list->i_size; +} + +void* +list_remove_front(List *p_list) { + if (list_empty(p_list)) + return (NULL); + + ListElem *p_elem = p_list->p_first; + p_list->p_first = p_elem->p_next; + + if (p_list->p_first) + p_list->p_first->p_prev = NULL; + + void *p_val = p_elem->p_val; + free(p_elem); + + --p_list->i_size; + + return (p_val); +} + +void* +list_remove_back(List *p_list) { + if (list_empty(p_list)) + return (NULL); + + ListElem *p_elem = p_list->p_last; + p_list->p_last = p_elem->p_prev; + p_list->p_last->p_next = NULL; + + void *p_val = p_elem->p_val; + free(p_elem); + + --p_list->i_size; + + return (p_val); +} + +void +list_clear(List *p_list) { + for (;!list_empty(p_list); list_remove_front(p_list)); +} + +void +list_clear_and_free_vals(List *p_list) { + void *p_void = NULL; + for (;!list_empty(p_list); p_void = list_remove_front(p_list)) + if (p_void) + free(p_void); +} + +void +list_delete(List *p_list) { + list_clear(p_list); + free(p_list); +} + +void +list_delete_cb(void *p_list) { + list_delete(p_list); +} + +void +list_delete_and_free_vals(List *p_list) { + list_clear_and_free_vals(p_list); + free(p_list); +} + +unsigned +list_size(List *p_list) { + return (p_list->i_size); +} + +void +list_iterate(List *p_list, void (*func)(void *)) { + ListElem *p_elem = p_list->p_first; + + while (p_elem) { + (*func) (p_elem->p_val); + p_elem = p_elem->p_next; + } +} + +void +list_iterate2(List *p_list, void (*func)(void *, void *), void *p_void) { + ListElem *p_elem = p_list->p_first; + + while (p_elem) { + (*func) (p_elem->p_val, p_void); + p_elem = p_elem->p_next; + } +} + +void +list_iterate2_ptr(List *p_list, void (*func)(void *, void *), void *p_void) { + ListElem *p_elem = p_list->p_first; + + while (p_elem) { + (*func) (&p_elem->p_val, p_void); + p_elem = p_elem->p_next; + } +} + +void +list_iterate3(List *p_list, + void (*func)(void *, void *, void *), + void *p_void1, void *p_void2) { + ListElem *p_elem = p_list->p_first; + + while (p_elem) { + (*func) (p_elem->p_val, p_void1, p_void2); + p_elem = p_elem->p_next; + } +} + +void +list_iterate3_ptr(List *p_list, + void (*func)(void *, void *, void *), + void *p_void1, void *p_void2) { + ListElem *p_elem = p_list->p_first; + + while (p_elem) { + (*func) (&p_elem->p_val, p_void1, p_void2); + p_elem = p_elem->p_next; + } +} + +void +list_remove_elem(List *p_list, ListElem *p_elem_remove) { + ListElem *p_elem = p_list->p_first; + + if (p_elem == p_elem_remove) { + p_list->p_first = p_elem->p_next; + p_list->p_first->p_prev = NULL; + --p_list->i_size; + return; + } + + while ((p_elem = p_elem->p_next)) { + if (p_elem == p_elem_remove) { + ListElem *p_prev = p_elem->p_prev; + ListElem *p_next = p_elem->p_next; + + if (p_next) { + p_prev->p_next = p_next; + p_next->p_prev = p_prev; + + } else { + p_prev->p_next = NULL; + p_list->p_last = p_prev; + } + + --p_list->i_size; + free(p_elem_remove); + return; + } + } +} + +ListIterator* +listiterator_new(List *p_list) { + if (!p_list) + return (NULL); + + ListIterator *p_iter = malloc(sizeof(ListIterator)); + + p_iter->p_cur = p_list->p_first; + p_iter->b_reverse = false; + p_iter->func = NULL; + + return (p_iter); +} + +ListIterator* +listiterator_new_from_elem(ListElem *p_listelem) { + if (!p_listelem) + return (NULL); + + ListIterator *p_iter = malloc(sizeof(ListIterator)); + + p_iter->p_cur = p_listelem; + p_iter->b_reverse = false; + p_iter->func = NULL; + + return (p_iter); +} + +ListIterator* +listiterator_new_from_elem_reverse(ListElem *p_listelem) { + ListIterator *p_iter = listiterator_new_from_elem(p_listelem); + + if (!p_iter) + return (NULL); + + p_iter->b_reverse = true; + + return (p_iter); +} + +ListIterator* +listiterator_new_reverse(List *p_list) { + if (!p_list) + return (NULL); + + ListIterator *p_iter = listiterator_new(p_list); + + p_iter->p_cur = p_list->p_last; + p_iter->b_reverse = true; + + return (p_iter); +} + +void +listiterator_delete(ListIterator *p_iter) { + if (p_iter) + free(p_iter); +} + +void* +listiterator_next(ListIterator *p_iter) { + if (p_iter->p_cur) { + void *p_ret = p_iter->p_cur->p_val; + + if (p_iter->b_reverse) + p_iter->p_cur = p_iter->p_cur->p_prev; + + else + p_iter->p_cur = p_iter->p_cur->p_next; + + if (p_iter->func) + return ((*p_iter->func) (p_ret)); + + else + return (p_ret); + } + + return (NULL); +} + +void* +listiterator_prev(ListIterator *p_iter) { + if (p_iter->p_cur) { + void *p_ret = p_iter->p_cur->p_val; + + if (!p_iter->b_reverse) + p_iter->p_cur = p_iter->p_cur->p_prev; + + else + p_iter->p_cur = p_iter->p_cur->p_next; + + if (p_iter->func) + return ((*p_iter->func) (p_ret)); + + else + return (p_ret); + } + + return (NULL); +} + +void* +listiterator_current(ListIterator *p_iter) { + if (p_iter->p_cur) + return (p_iter->p_cur->p_val); + + return (NULL); +} + +ListElem* +listiterator_current_elem(ListIterator *p_iter) { + if (p_iter->p_cur) + return (p_iter->p_cur); + + return (NULL); +} + +ListElem* +listiterator_prev_elem(ListIterator *p_iter) { + if (p_iter->p_cur) { + if (!p_iter->b_reverse) + return (p_iter->p_cur->p_prev); + + else + return (p_iter->p_cur->p_next); + } + + return (NULL); +} + +void* +listiterator_end(ListIterator *p_iter) { + void *p_ret = NULL; + + while (listiterator_has_next(p_iter)) + p_ret = listiterator_next(p_iter); + + return (p_ret); +} + +_Bool +listiterator_current_elem_equals(ListIterator *p_iter, ListElem *p_listelem) { + if (!p_iter || !p_listelem) + return (false); + + ListElem *p_listelem_current = listiterator_current_elem(p_iter); + + if (!p_listelem_current) + return (false); + + else if (p_listelem_current->p_next != p_listelem->p_next) + return (false); + + else if (p_listelem_current->p_prev != p_listelem->p_prev) + return (false); + + else if (p_listelem_current->p_val != p_listelem->p_val) + return (false); + + return (true); +} + +ListElem* +listiterator_next_elem(ListIterator *p_iter) { + if (p_iter->p_cur) { + ListElem *p_ret = p_iter->p_cur; + + p_iter->p_cur = p_iter->b_reverse ? + p_iter->p_cur->p_prev : p_iter->p_cur->p_next; + + return (p_ret); + } + + return (NULL); +} + +_Bool +listiterator_has_next(ListIterator *p_iter) { + return (p_iter->p_cur != NULL ? true : false); +} + + +ListIteratorState* +listiterator_get_state(ListIterator *p_iter) { + ListIteratorState *p_state = malloc(sizeof(ListIteratorState)); + + p_state->p_cur = p_iter->p_cur; + p_state->b_reverse = p_iter->b_reverse; + + return (p_state); +} + +void +listiterator_set_state(ListIterator *p_iter, ListIteratorState *p_state) { + p_iter->p_cur = p_state->p_cur; + p_iter->b_reverse = p_state->b_reverse; +} + +void +listiteratorstate_delete(ListIteratorState *p_state) { + free(p_state); +} diff --git a/src/data/list.h b/src/data/list.h new file mode 100644 index 0000000..fb6a9b8 --- /dev/null +++ b/src/data/list.h @@ -0,0 +1,118 @@ +/*:* + *: File: ./src/data/list.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 LIST_H +#define LIST_H + +#include <stdlib.h> + +#include "../defines.h" + +#define list_first(l) l->p_first->p_val +#define list_last(l) l->p_last->p_val +#define listiterator_set_callback(i,cb) i->func = cb + +typedef struct ListElem_ { + struct ListElem_ *p_next; + struct ListElem_ *p_prev; + void *p_val; +} ListElem; + +typedef struct { + ListElem *p_first; + ListElem *p_last; + unsigned i_size; +} List; + +typedef struct { + ListElem *p_cur; + _Bool b_reverse; + void* (*func)(void *); +} ListIterator; + +typedef struct { + ListElem *p_cur; + _Bool b_reverse; +} ListIteratorState; + +List *list_new(); +List *list_copy(List *p_list); +List *list_copy2(List *p_list, void* (*func)(void *)); +ListElem *listelem_new(); +_Bool list_empty(List *p_list); +void list_concat_front(List *p_list1, List *p_list2); +void list_concat_back(List *p_list1, List *p_list2); +void list_add_front(List *p_list, void *p_val); +void list_add_back(List *p_list, void *p_val); +void *list_remove_front(List *p_list); +void *list_remove_back(List *p_list); +void list_clear(List *p_list); +void list_clear_and_free_vals(List *p_list); +void list_delete(List *p_list); +void list_delete_cb(void *p_list); +void list_delete_and_free_vals(List *p_list); +unsigned list_size(List *p_list); +void list_iterate(List *p_list, void (*func)(void *)); +void list_iterate2_ptr(List *p_list, + void (*func)(void *, void *), + void *p_void); +void list_iterate2(List *p_list, + void (*func)(void *, void *), + void *p_void); +void list_iterate3(List *p_list, + void (*func)(void *, void *, void *), + void *p_void1, void *p_void2); +void list_iterate3_ptr(List *p_list, + void (*func)(void *, void *, void *), + void *p_void1, void *p_void2); +ListIterator* listiterator_new(List *p_list); +ListIterator* listiterator_new_from_elem(ListElem *p_listelem); +ListIterator* listiterator_new_from_elem_reverse(ListElem *p_listelem); +ListIterator* listiterator_new_reverse(List *p_list); +void listiterator_delete(ListIterator *p_iter); +void* listiterator_next(ListIterator *p_iter); +void* listiterator_prev(ListIterator *p_iter); +void* listiterator_current(ListIterator *p_iter); +ListElem* listiterator_current_elem(ListIterator *p_iter); +ListElem* listiterator_prev_elem(ListIterator *p_iter); +void* listiterator_end(ListIterator *p_iter); +_Bool listiterator_has_next(ListIterator *p_iter); +_Bool listiterator_current_elem_equals(ListIterator *p_iter, ListElem *p_listelem); +ListElem* listiterator_next_elem(ListIterator *p_iter); +void list_remove_elem(List *p_list, ListElem *p_elem_remove); +ListIteratorState* listiterator_get_state(ListIterator *p_iter); +void listiterator_set_state(ListIterator *p_iter, ListIteratorState *p_state); +void listiteratorstate_delete(ListIteratorState *p_state); + +#endif diff --git a/src/data/map.c b/src/data/map.c new file mode 100644 index 0000000..3c95dc2 --- /dev/null +++ b/src/data/map.c @@ -0,0 +1,289 @@ +/*:* + *: File: ./src/data/map.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "map.h" + +Map* +map_new(int i_max_size) { + return (map_new_named(i_max_size, "noname")); +} + +Map* +map_new_named(int i_max_size, char *c_name) { + Map *p_map = malloc(sizeof(Map)); + + p_map->c_name = c_name; + p_map->pc_keys = calloc(i_max_size, sizeof(char*)); + p_map->pp_vals = calloc(i_max_size, sizeof(void*)); + + for (int i = 0; i < i_max_size; ++i) { + p_map->pc_keys[i] = NULL; + p_map->pp_vals[i] = NULL; + } + + p_map->i_size = 0; + p_map->i_max_size = i_max_size; + + return (p_map); +} + +_Bool +map_empty(Map *p_map) { + return (p_map->i_size == 0); +} + +_Bool +map_full(Map *p_map) { + return (p_map->i_size == p_map->i_max_size); +} + +int +map_next_free_addr(Map *p_map) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] == NULL) + return (i); + + ERROR("No free space left in the map (%s)", p_map->c_name); + + // This point should not be reached! + return (0); +} + +_Bool +map_insert(Map *p_map, char *c_key, void *p_val) { + int i_free_addr = map_next_free_addr(p_map); + int i_len = strlen(c_key); + + p_map->pc_keys[i_free_addr] = STR_NEW(i_len+1); + strncpy(p_map->pc_keys[i_free_addr], c_key, i_len); + p_map->pp_vals[i_free_addr] = p_val; + + ++p_map->i_size; + return (true); +} + +_Bool +map_insert2(Map *p_map, char *c_key1, char *c_key2, void *p_val) { + char c_key[HASH_MKEYLEN]; + sprintf(c_key, "%s%s%s", c_key1, SEP, c_key2); + return (map_insert(p_map, c_key, p_val)); +} + +_Bool +map_insert_if_not_exists(Map *p_map, char *c_key, void *p_val) { + void *p_void = map_get(p_map, c_key); + + if (p_void) + return (false); + + return (map_insert(p_map, c_key, p_val)); + + return (true); +} + +void +map_remove(Map *p_map, char *c_key) { + if (map_empty(p_map)) + return; + + int i_index = map_get_addr(p_map, c_key); + if (i_index < 0) + return; + + free(p_map->pc_keys[i_index]); + p_map->pc_keys[i_index] = NULL; + p_map->pp_vals[i_index] = NULL; + --p_map->i_size; +} + +void* +map_get(Map *p_map, char *c_key) { + if (map_empty(p_map)) + return (NULL); + + int i_index = map_get_addr(p_map, c_key); + return (i_index >= 0 ? p_map->pp_vals[i_index] : NULL); +} + +void* +map_get2(Map *p_map, char *c_key1, char *c_key2) { + char c_key[HASH_MKEYLEN]; + sprintf(c_key, "%s%s%s", c_key1, SEP, c_key2); + return (map_get(p_map, c_key)); +} + + +_Bool +map_exists(Map *p_map, char *c_key) { + if (map_empty(p_map)) + return (false); + + int i_index = map_get_addr(p_map, c_key); + return (i_index >= 0 ? true : false); +} + +_Bool +map_exists2(Map *p_map, char *c_key1, char *c_key2) { + if (map_empty(p_map)) + return (false); + + char c_key[HASH_MKEYLEN]; + sprintf(c_key, "%s%s%s:", c_key1, SEP, c_key2); + + int i_index = map_get_addr(p_map, c_key); + return i_index >= 0 ? true : false; +} + +char* +map_get_key(Map *p_map, void *p_val) { + if (map_empty(p_map)) + return (NULL); + + for (int i = 0; i < p_map->i_max_size; ++i) + if ((unsigned) p_map->pp_vals[i] == (unsigned) p_val) + return (p_map->pc_keys[i]); + + return (NULL); +} + +int +map_get_addr(Map *p_map, char *c_key) { + if (map_empty(p_map)) + return (-1); + + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL && strcmp(p_map->pc_keys[i], c_key) == 0) + return (i); + + return (-1); +} + +void +map_clear(Map *p_map) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) { + free(p_map->pc_keys[i]); + p_map->pc_keys[i] = NULL; + p_map->pp_vals[i] = NULL; + } + + p_map->i_size = 0; +} + +void +map_clear_and_free_vals(Map *p_map) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) { + free(p_map->pc_keys[i]); + + if (p_map->pp_vals[i]) + free(p_map->pp_vals[i]); + + p_map->pc_keys[i] = NULL; + p_map->pp_vals[i] = NULL; + } + + p_map->i_size = 0; +} + +void +map_delete(Map *p_map) { + map_clear(p_map); + free(p_map); +} + +void +map_delete_and_free_vals(Map *p_map) { + map_clear_and_free_vals(p_map); + free(p_map); +} + +void +map_print(Map *p_map) { + printf("Map<size=%d, max_size=%d>:", + map_get_size(p_map), map_get_max_size(p_map)); + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + printf("(%d,%s)", i, p_map->pc_keys[i]); + puts(""); +} + +void +map_iterate(Map *p_map, void (*func) (void *)) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i]); +} + +void +map_iterate_keys(Map *p_map, void (*func) (void *, char *)) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i], p_map->pc_keys[i]); +} + +void +map_iterate2(Map *p_map, void (*func) (void *, void *), void *p_void) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i], p_void); +} + +void +map_iterate2_keys(Map *p_map, + void (*func) (void *, void *, char *), + void *p_void) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i], p_void, p_map->pc_keys[i]); +} + +void +map_iterate3(Map *p_map, + void (*func) (void *, void *, void *), + void *p_void1, void *p_void2) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i], p_void1, p_void2); +} + +void +map_iterate3_keys(Map *p_map, + void (*func) (void *, void *, void *, char *), + void *p_void1, void *p_void2) { + for (int i = 0; i < p_map->i_max_size; ++i) + if (p_map->pc_keys[i] != NULL) + (*func) (p_map->pp_vals[i], p_void1, p_void2, p_map->pc_keys[i]); +} + diff --git a/src/data/map.h b/src/data/map.h new file mode 100644 index 0000000..c01dbe1 --- /dev/null +++ b/src/data/map.h @@ -0,0 +1,88 @@ +/*:* + *: File: ./src/data/map.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 MAP_H +#define MAP_H + +#include <stdlib.h> +#include <string.h> + +#include "../defines.h" +#define SEP "::" + +typedef struct { + char *c_name; + char **pc_keys; + void **pp_vals; + int i_size; + int i_max_size; +} Map; + +Map *map_new(int i_max_size); +Map *map_new_named(int i_max_size, char *c_name); +_Bool map_empty(Map *p_map); +_Bool map_full(Map *p_map); +int map_next_free_addr(Map *p_map); +_Bool map_insert(Map *p_map, char *c_key, void *p_val); +_Bool map_insert2(Map *p_map, char *c_key1, char *c_key2, void *p_val); +_Bool map_insert_if_not_exists(Map *p_map, char *c_key, void *p_val); +void map_remove(Map *p_map, char *c_key); +void *map_get(Map *p_map, char *c_key); +void *map_get2(Map *p_map, char *c_key1, char *c_key2); +_Bool map_exists(Map *p_map, char *c_key); +_Bool map_exists2(Map *p_map, char *c_key1, char *c_key2); +char *map_get_key(Map *p_map, void *p_val); +int map_get_addr(Map *p_map, char *c_key); +void map_clear(Map *p_map); +void map_clear_and_free_vals(Map *p_map); +void map_delete(Map *p_map); +void map_delete_and_free_vals(Map *p_map); +void map_print(Map *p_map); +void map_iterate(Map *p_map, void (*func) (void *)); +void map_iterate_keys(Map *p_map, void (*func) (void *, char *)); +void map_iterate2(Map *p_map, void (*func) (void *, void *), void *p_void); +void map_iterate2_keys(Map *p_map, + void (*func) (void *, void *, char *), + void *p_void); +void map_iterate3(Map *p_map, + void (*func) (void *, void *, void *), + void *p_void1, void *p_void2); +void map_iterate3_keys(Map *p_map, + void (*func) (void *, void *, void *, char *), + void *p_void1, void *p_void2); + +#define map_get_size(map) map->i_size +#define map_get_max_size(map) map->i_max_size + +#endif diff --git a/src/data/queue.c b/src/data/queue.c new file mode 100644 index 0000000..63987a0 --- /dev/null +++ b/src/data/queue.c @@ -0,0 +1,210 @@ +/*:* + *: File: ./src/data/queue.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "queue.h" + +#include <stdlib.h> + +Queue* +queue_new() { + Queue *p_queue = (Queue *) malloc(sizeof(Queue)); + + p_queue->p_first = 0; + p_queue->p_last = 0; + p_queue->i_size = 0; + + return p_queue; +} + +QueueElem* +queueelem_new() { + return queueelem_new_t(TYPE_UNKNOWN); +} + +QueueElem* +queueelem_new_t(TYPE type) { + QueueElem *p_elem = (QueueElem *) malloc(sizeof(QueueElem)); + + p_elem->p_next = 0; + p_elem->p_val = 0; + p_elem->type = type; + + return p_elem; +} + +_Bool +queue_empty(Queue *p_queue) { + if (p_queue == NULL) + return 0; + + return p_queue->i_size == 0; +} + +void +queue_push(Queue *p_queue, void *p_val) { + queue_push_t(p_queue, p_val, TYPE_UNKNOWN); +} + +void +queue_push_t(Queue *p_queue, void *p_val, TYPE type) { + QueueElem *p_elem = queueelem_new_t(type); + p_elem->p_val = p_val; + + if (0 == p_queue->i_size++) + p_queue->p_first = p_elem; + else + p_queue->p_last->p_next = p_elem; + + p_queue->p_last = p_elem; +} + +void* +queue_pop(Queue *p_queue) { + TYPE type; + return queue_pop_t(p_queue, &type); +} + +void* +queue_pop_t(Queue *p_queue, TYPE *p_type) { + if (queue_empty(p_queue)) + return 0; + + QueueElem *p_elem = p_queue->p_first; + p_queue->p_first = p_elem->p_next; + + --p_queue->i_size; + + void *p_ret = p_elem->p_val; + *p_type = p_elem->type; + free(p_elem); + return p_ret; +} + +void +queue_clear(Queue *p_queue) { + for (;!queue_empty(p_queue); queue_pop(p_queue)); +} + +void +queue_delete(Queue *p_queue) { + queue_clear(p_queue); + free(p_queue); +} + +unsigned +queue_size(Queue *p_queue) { + return p_queue->i_size; +} + +void +queue_iterate(Queue *p_queue, void (*func)(void *)) { + QueueElem *p_elem = p_queue->p_first; + while (p_elem) { + if (p_elem->p_val) + (*func) (p_elem->p_val); + + p_elem = p_elem->p_next; + } +} + +void +queue_iterate_t(Queue *p_queue, void (*func)(void *, TYPE)) { + QueueElem *p_elem = p_queue->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 +queue_iterate_tl(Queue *p_queue, void (*func)(void *, TYPE, _Bool)) { + QueueElem *p_elem = p_queue->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; + } +} + +QueueIter* +queueiter_new(Queue *p_queue) { + QueueIter *p_iter = + (QueueIter *) malloc(sizeof(QueueIter)); + + p_iter->p_current = NULL; + p_iter->p_next = p_queue->p_first; + p_iter->i_left = queue_size(p_queue); + p_iter->p_queue = p_queue; + + return p_iter; +} + +void +queueiter_delete(QueueIter *p_iter) { + free(p_iter); +} + +void* +queueiter_next(QueueIter *p_iter) { + TYPE type; + return queueiter_next_t(p_iter, &type); +} + +void* +queueiter_next_t(QueueIter *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 +queueiter_left(QueueIter *p_iter) { + return p_iter->i_left; +} + +Queue* +queueiter_queue(QueueIter *p_iter) { + return p_iter->p_queue; +} + diff --git a/src/data/queue.h b/src/data/queue.h new file mode 100644 index 0000000..227ce29 --- /dev/null +++ b/src/data/queue.h @@ -0,0 +1,81 @@ +/*:* + *: File: ./src/data/queue.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 QUEUE_H +#define QUEUE_H + +#include "types.h" + +typedef struct QueueElem_ { + struct QueueElem_ *p_next; + void *p_val; + TYPE type; +} QueueElem; + +typedef struct { + QueueElem *p_first; + QueueElem *p_last; + unsigned i_size; +} Queue; + +typedef struct { + unsigned i_left; + Queue *p_queue; + QueueElem *p_current; + QueueElem *p_next; +} QueueIter; + +Queue *queue_new(); +QueueElem *queueelem_new(); +QueueElem *queueelem_new_t(TYPE type); +_Bool queue_empty(Queue *p_queue); +void queue_push(Queue *p_queue, void *p_val); +void queue_push_t(Queue *p_queue, void *p_val, TYPE type); +void *queue_pop(Queue *p_queue); +void *queue_pop_t(Queue *p_queue, TYPE *p_type); +void queue_clear(Queue *p_queue); +void queue_delete(Queue *p_queue); +unsigned queue_size(Queue *p_queue); +void queue_iterate(Queue *p_queue, void (*func)(void *)); +void queue_iterate_t(Queue *p_queue, void (*func)(void *, TYPE)); +void queue_iterate_tl(Queue *p_queue, void (*func)(void *, TYPE, _Bool)); + +QueueIter *queueiter_new(Queue *p_queue); +void queueiter_delete(QueueIter *p_iter); +void *queueiter_next(QueueIter *p_iter); +void *queueiter_next_t(QueueIter *p_iter, TYPE *p_type); +unsigned queueiter_left(QueueIter *p_iter); +Queue *queueiter_queue(QueueIter *p_iter); + +#endif diff --git a/src/data/stack.c b/src/data/stack.c new file mode 100644 index 0000000..e6a60a4 --- /dev/null +++ b/src/data/stack.c @@ -0,0 +1,271 @@ +/*:* + *: File: ./src/data/stack.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "stack.h" + +#include "../defines.h" + +Stack* +stack_new() { + Stack *p_stack = (Stack *) malloc(sizeof(Stack)); + + p_stack->p_first = p_stack->p_last = NULL; + p_stack->i_size = 0; + + return (p_stack); +} + +StackElem* +stackelem_new() { + StackElem *p_elem = (StackElem *) malloc(sizeof(StackElem)); + + p_elem->p_next = NULL; + p_elem->p_val = NULL; + + return (p_elem); +} + +_Bool +stack_empty(Stack *p_stack) { + return (p_stack->i_size == 0); +} + +void +stack_push(Stack *p_stack, void *p_val) { + StackElem *p_elem = stackelem_new(); + + p_elem->p_val = p_val; + p_elem->p_next = p_stack->p_first; + p_stack->p_first = p_elem; + + if (p_stack->p_last == NULL) + p_stack->p_last = p_stack->p_first; + + ++p_stack->i_size; +} + +void* +stack_pop(Stack *p_stack) { + if (stack_empty(p_stack)) + return (NULL); + + StackElem *p_elem = p_stack->p_first; + p_stack->p_first = p_elem->p_next; + + void *p_val = p_elem->p_val; + free(p_elem); + --p_stack->i_size; + + if (p_stack->i_size == 0) + p_stack->p_last = NULL; + + return (p_val); +} + +void* +stack_top(Stack *p_stack) { + if (stack_empty(p_stack)) + return (NULL); + + return (p_stack->p_first->p_val); +} + +void +stack_clear(Stack *p_stack) { + for (;!stack_empty(p_stack); stack_pop(p_stack)); +} + +void +stack_delete(Stack *p_stack) { + stack_clear(p_stack); + free(p_stack); +} + +void +stack_delete_and_free(Stack *p_stack) { + for (;!stack_empty(p_stack); free(stack_pop(p_stack))); + stack_delete(p_stack); +} + +unsigned +stack_size(Stack *p_stack) { + if (!p_stack) + return (0); + + return (p_stack->i_size); +} + +void +stack_merge(Stack *p_stack, Stack *p_stack_merge) { + if (stack_empty(p_stack_merge)) + return; + + if (stack_empty(p_stack)) { + p_stack->p_first = p_stack_merge->p_first; + p_stack->p_last = p_stack_merge->p_last; + p_stack->i_size = p_stack_merge->i_size; + + } else { + StackElem *p_old_first = p_stack->p_first; + + p_stack->p_first = p_stack_merge->p_first; + p_stack_merge->p_last->p_next = p_old_first; + p_stack->i_size += p_stack_merge->i_size; + } + + p_stack_merge->p_first = p_stack_merge->p_last = NULL; + p_stack_merge->i_size = 0; +} + +void +stack_concat(Stack *p_stack, Stack *p_stack_concat) { + if (stack_empty(p_stack_concat)) + return; + + Stack *p_stack_tmp = stack_new(); + + StackIterator *p_iter = stackiterator_new(p_stack_concat); + + while (stackiterator_has_next(p_iter)) + stack_push(p_stack_tmp, stackiterator_next(p_iter)); + + stackiterator_delete(p_iter); + + while (!stack_empty(p_stack_tmp)) + stack_push(p_stack, stack_pop(p_stack_tmp)); + + stack_delete(p_stack_tmp); +} + +void +stack_iterate(Stack *p_stack, void (*func)(void *p_void)) { + if (!p_stack) + return; + + StackElem *p_elem = p_stack->p_first; + + while (p_elem) { + (*func)(p_elem->p_val); + p_elem = p_elem->p_next; + } +} + +void +stack_iterate2(Stack *p_stack, void (*func)(void *p_void, void *p_void2), + void *p_void_arg) { + if (!p_stack) + return; + + StackElem *p_elem = p_stack->p_first; + + while (p_elem) { + (*func)(p_elem->p_val, p_void_arg); + p_elem = p_elem->p_next; + } +} + +void +stack_iterate_level(Stack *p_stack, void (*func)(void *p_void, + int i_level)) { + if (!p_stack) + return; + + StackElem *p_elem = p_stack->p_first; + + int i_level = 0; + while (p_elem) { + (*func)(p_elem->p_val, i_level++); + p_elem = p_elem->p_next; + } +} + +StackIterator* +stackiterator_new(Stack *p_stack) { + StackIterator *p_iter = malloc(sizeof(StackIterator)); + + p_iter->p_current = p_stack->p_first; + p_iter->p_prev = NULL; + + return (p_iter); +} + +void +stackiterator_delete(StackIterator *p_iter) { + free(p_iter); +} + +void* +stackiterator_next(StackIterator *p_iter) { + if (!p_iter) + return (NULL); + + StackElem *p_elem = p_iter->p_current; + + if (!p_elem) + return (NULL); + + p_iter->p_prev = p_iter->p_current; + p_iter->p_current = p_elem->p_next; + + return (p_elem->p_val); +} + +_Bool +stackiterator_has_next(StackIterator *p_iter) { + return (p_iter->p_current ? true : false); +} + +_Bool +stackiterator_remove_prev(StackIterator *p_iter) { + StackElem *p_prev = p_iter->p_prev; + + if (p_prev == NULL) + return (false); + + StackElem *p_next = p_prev->p_next; + + if (p_next == NULL) + return (false); + + p_prev->p_val = p_next->p_val; + p_prev->p_next = p_next->p_next; + + + free(p_next); + + p_iter->p_current = p_prev; + p_iter->p_prev = NULL; + + return (true); +} diff --git a/src/data/stack.h b/src/data/stack.h new file mode 100644 index 0000000..395dd32 --- /dev/null +++ b/src/data/stack.h @@ -0,0 +1,79 @@ +/*:* + *: File: ./src/data/stack.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 STACK_H +#define STACK_H + +#include <stdlib.h> + +typedef struct StackElem_ { + struct StackElem_ *p_next; + void *p_val; +} StackElem; + +typedef struct { + StackElem *p_first; + StackElem *p_last; // Only needed for stack_merge + unsigned i_size; +} Stack; + +typedef struct { + StackElem *p_current; + StackElem *p_prev; +} StackIterator; + +Stack *stack_new(); +StackElem *stackelem_new(); +_Bool stack_empty(Stack *p_stack); +void stack_iterate(Stack *p_stack, void (*func)(void *p_void)); +void stack_iterate2(Stack *p_stack, void (*func)(void *p_void, void *p_void2), + void *p_void_arg); +void stack_iterate_level(Stack *p_stack, void (*func)(void *p_void, + int i_level)); +void stack_push(Stack *p_stack, void *p_val); +void *stack_pop(Stack *p_stack); +void *stack_top(Stack *p_stack); +void stack_clear(Stack *p_stack); +void stack_delete(Stack *p_stack); +void stack_delete_and_free(Stack *p_stack); +unsigned stack_size(Stack *p_stack); +void stack_merge(Stack *p_stack, Stack *p_stack_merge); +void stack_concat(Stack *p_stack, Stack *p_stack_concat); +StackIterator* stackiterator_new(Stack *p_stack); +void stackiterator_delete(StackIterator *p_iter); +_Bool stackiterator_has_next(StackIterator *p_iter); +void* stackiterator_next(StackIterator *p_iter); +_Bool stackiterator_remove_prev(StackIterator *p_iter); + +#endif diff --git a/src/data/tree.c b/src/data/tree.c new file mode 100644 index 0000000..c55dcf1 --- /dev/null +++ b/src/data/tree.c @@ -0,0 +1,215 @@ +/*:* + *: File: ./src/data/tree.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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); + + printf(" %d", (int) treenode_get_val(ptn)); +} + +void +_tree_print(TreeNode *p_treenode, int i_indent) { + //TokenType tt = (TokenType)treenode_get_val(p_treenode); + + //_indent(i_indent); + //printf("%s:", tt_get_name(tt)); + + array_iterate2(p_treenode->p_array_childs, _tree_print_cb, (void*) 0); + + 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; +} + diff --git a/src/data/tree.h b/src/data/tree.h new file mode 100644 index 0000000..ce9ecc4 --- /dev/null +++ b/src/data/tree.h @@ -0,0 +1,106 @@ +/*:* + *: File: ./src/data/tree.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 TREE_H +#define TREE_H + +#include "../defines.h" +#include "array.h" +#include "stack.h" + +#ifdef PBSC +#include "../core/token.h" +#endif + +#define TREE_PRINT_INDENT 3 + +#define tree_get_root(t) t->p_treenode_root +#define tree_set_root(t,tn) t->p_treenode_root = tn +#define treenode_get_num_childs(tn) array_get_size(tn->p_array_childs) +#define treenode_get_tnt(tn) tn->tnt +#define treenode_get_val(tn) tn->p_val +#define treenode_get_val2(tn) tn->p_val2 +#define treenode_set_tnt(tn,t) tn->tnt = t +#define treenode_set_val(tn,v) tn->p_val = v +#define treenode_set_val2(tn,v) tn->p_val2 = v +#define treenode_insert_child treenode_insert_right +#define treenode_get_childs(tn) tn->p_array_childs +#define treenode_get_child(tn,i) array_get(tn->p_array_childs,i) +#define treenode_get_first_child(tn) array_get_first(tn->p_array_childs) +#define treenode_get_last_child(tn) array_get_last(tn->p_array_childs) + +typedef enum { + IS_NOTLEAF, + IS_LEAF, +} TreeNodeType; + +typedef struct { + TreeNodeType tnt; + Array *p_array_childs; + void *p_val; + void *p_val2; +} TreeNode; + +typedef struct { + TreeNode *p_treenode_root; +} Tree; + +typedef struct { + TreeNode *ptn; + int i_pos; +} TreeIteratorState; + +typedef struct { + Stack *p_stack; + TreeIteratorState *p_state; +} TreeIterator; + +Tree* tree_new(); +void tree_delete(Tree *p_tree); +void tree_print(Tree *p_tree); +TreeNode* treenode_new(void *p_val); +TreeNode* treenode_new2(void *p_val, void *p_val2); +void treenode_delete(TreeNode *p_treenode); +void treenode_insert_left(TreeNode *p_treenode, TreeNode *p_treenode2); +void treenode_insert_right(TreeNode *p_treenode, TreeNode *p_treenode2); + +TreeIteratorState* treeiteratorstate_new(TreeNode *ptn); +void treeiteratorstate_delete(TreeIteratorState *p_state); + +TreeIterator* treeiterator_new(Tree *p_tree); +void treeiterator_delete(TreeIterator *p_iter); +_Bool treeiterator_has_next(TreeIterator *p_iter); +TreeNode* treeiterator_next(TreeIterator *p_iter); + +#endif diff --git a/src/data/tupel.c b/src/data/tupel.c new file mode 100644 index 0000000..68c0247 --- /dev/null +++ b/src/data/tupel.c @@ -0,0 +1,53 @@ +/*:* + *: File: ./src/data/tupel.c + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 "tupel.h" + +#include <stdlib.h> + +Tupel* +tupel_new() { + Tupel *p_tupel = (Tupel *) malloc(sizeof(Tupel)); + + p_tupel->a = NULL; + p_tupel->b = NULL; + p_tupel->c = NULL; + + return p_tupel; +} + +void +tupel_delete(Tupel *p_tupel) { + free(p_tupel); +} diff --git a/src/data/tupel.h b/src/data/tupel.h new file mode 100644 index 0000000..e5d0fe7 --- /dev/null +++ b/src/data/tupel.h @@ -0,0 +1,47 @@ +/*:* + *: File: ./src/data/tupel.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 TUPEL_H +#define TUPEL_H + +typedef struct { + void *a; + void *b; + void *c; +} Tupel; + +Tupel *tupel_new(); +void tupel_delete(Tupel *p_tupel); + +#endif diff --git a/src/data/types.h b/src/data/types.h new file mode 100644 index 0000000..2899dfe --- /dev/null +++ b/src/data/types.h @@ -0,0 +1,64 @@ +/*:* + *: File: ./src/data/types.h + *: A simple Fype interpreter + *: + *: WWW: http://fype.buetow.org + *: AUTHOR: http://paul.buetow.org + *: E-Mail: fype at dev.buetow.org + *: + *: The Fype Language; (c) 2005 - 2010 - Dipl.-Inform. (FH) Paul C. Buetow + *: + *: 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 buetow.org 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 C. 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 C. 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 TYPES_H +#define TYPES_H + +typedef enum { + TYPE_UNKNOWN, + TYPE_NUMBER, + TYPE_STRING, + TYPE_VOIDP, + TYPE_SYMVAR, + TYPE_VARIABLE, + TYPE_REGEXPR, + TYPE_OPERATOR, + TYPE_STACK, + TYPE_TUPEL, + TYPE_HASH, + TYPE_DAT, + TYPE_ARG_DAT, + TYPE_ARGS_DAT, + TYPE_STATEMENT_DAT, + TYPE_CODE_DAT +} TYPE; + +typedef enum { + RET_OK, + RET_ERROR = -1, + RET_NO_SPACE = -2, + RET_OCCUPIED = -3 +} RETCODE; + +#endif |
