#ifndef UTIL_H
#define UTIL_H
#include <memory.h>
#include <stdlib.h>
#include "error.h"
template <class contents>
struct LispNode {
contents* car;
LispNode* cdr;
inline LispNode(contents* value)
: car(value), cdr(0) { }
inline LispNode(contents* value, LispNode* next)
: car (value), cdr(next) { }
inline LispNode(LispNode* prev, contents* value)
: car(value), cdr(prev->cdr) { prev->cdr = this; }
};
template <class contents>
struct LispList {
LispNode<contents> *first;
inline LispList()
{
first = 0;
}
inline LispList(LispNode<contents>* _first)
{
first = _first;
}
inline LispList(LispList &init)
{
first = init.first;
}
inline int is_empty()
{
return first == 0;
}
inline int is_present(contents* element)
{
for (LispNode<contents>* node = first; node; node = node->cdr)
if (node->car == element)
return 1;
return 0;
}
inline int count()
{
int n = 0;
for (LispNode<contents>* node = first; node; node = node->cdr)
n++;
return n;
}
inline void add_head(LispNode<contents>* new_element)
{
new_element->cdr = first;
first = new_element;
}
inline void add(LispNode<contents>* new_element)
{
add_head (new_element);
}
inline void add_tail(LispNode<contents>* new_element)
{
LispNode<contents>** pred = &first;
while(*pred)
pred = &(*pred)->cdr;
*pred = new_element;
new_element->cdr = 0;
}
inline void add_head_new(contents* new_element)
{
first = new LispNode<contents>(new_element, first);
}
inline void add_head(contents* new_element)
{
add_head_new(new_element);
}
inline void add_tail_new(contents* new_element)
{
LispNode< contents >** pred = &first;
while (*pred)
pred = &(*pred)->cdr;
*pred = new LispNode< contents >(new_element);
}
inline void add_tail(contents* new_element)
{
add_tail_new(new_element);
}
inline void add_new(contents* new_element)
{
add_head_new(new_element);
}
inline void add(contents* new_element)
{
add_new(new_element);
}
inline void add_new_once(contents* new_element)
{
if (!is_present(new_element))
add_head_new(new_element);
}
inline void add_tail_once(contents *new_element)
{
if (!is_present(new_element))
add_tail_new(new_element);
}
inline LispNode<contents>* rem_head ()
{
LispNode<contents>* n = first;
if (n) {
first = first->cdr;
}
return n;
}
inline LispNode<contents>* remove ()
{
return( rem_head() );
}
inline void remove (LispNode<contents>* node)
{
for (LispNode<contents> **pp = &first; *pp; pp = &(*pp)->cdr)
if (*pp == node) {
*pp = (*pp)->cdr;
return;
}
}
inline void rem_del (contents* element)
{
LispNode<contents>** pp = &first;
while (*pp) {
if ((*pp)->car == element) {
LispNode<contents> *o = *pp;
*pp = o->cdr;
delete o;
} else
pp = &(*pp)->cdr;
}
}
inline void rem_del_all()
{
while (first) {
LispNode<contents>* old = first;
first = first->cdr;
delete old;
}
}
inline void put( contents* c )
{
add_tail( c );
}
inline void put_head( contents* c )
{
add_head( c );
}
inline void put_tail( contents* c )
{
add_tail( c );
}
#if 0
inline contents *get(contents *element)
{
contents *c = 0;
for (LispNode<contents> *node = first; node; node = node->cdr)
{
if (node->car == element)
{
c = node->car;
remove(node);
break;
}
}
return c;
}
#endif
inline contents* get_head()
{
contents *c = 0;
if(first) {
c = first->car;
delete rem_head();
}
return c;
}
inline contents* get()
{
return(get_head());
}
inline void push(contents* c)
{
put_head(c);
}
inline contents* pop()
{
return(get_head());
}
inline void pop_all()
{
rem_del_all();
}
inline void add_new(LispList other)
{
for (LispNode<contents>* n = other.first; n; n = n->cdr)
add_new(n->car);
}
inline void add_new_once(LispList other)
{
for (LispNode<contents>* n = other.first; n; n = n->cdr)
add_new_once(n->car);
}
inline void rem_del(LispList other)
{
for (LispNode<contents>* n = other.first; n; n = n->cdr)
rem_del(n->car);
}
};
template <class thetype>
struct DoubleLinkedNode
{
thetype* next;
thetype* prev;
DoubleLinkedNode()
{
next = prev = NULL;
}
void insert_after(thetype* n)
{
if (next != NULL)
next->prev = n;
n->next = next;
n->prev = (thetype*)this;
next = n;
}
void insert_before(thetype* n)
{
prev->next = n;
n->next = (thetype*)this;
n->prev = prev;
prev = n;
}
void remove()
{
assert(prev != NULL);
prev->next = next;
if (next != NULL)
next->prev = prev;
}
};
template <class thetype>
struct DoubleLinkedList : public DoubleLinkedNode<thetype>
{
DoubleLinkedList() : DoubleLinkedNode<thetype>() {};
void insert(thetype* n)
{
insert_after(n);
}
void add(thetype* n)
{
insert_after(n);
}
};
template <class T>
struct BufferArray {
T * items;
int num_items;
int num_slots;
int slot_inc;
void resize(int i)
{
items = (T*)realloc(items,sizeof(T)*i);
num_slots = i;
}
T & operator [](int index)
{
assert(index < num_items);
return items[index];
}
T & get(int index)
{
assert(index < num_items);
return items[index];
}
void add(T &item)
{
if (num_items == num_slots)
resize(num_slots+slot_inc);
memcpy(items+num_items,&item,sizeof(item));
num_items++;
}
BufferArray(int start_slots, int _slot_inc)
{
num_slots = start_slots;
slot_inc = _slot_inc;
assert(slot_inc > 0);
num_items = 0;
items = (T*)malloc(sizeof(T)*num_slots);
}
~BufferArray()
{
free(items);
}
};
#endif