123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // memory allocation and freeing:
- // TODO improve memory usage tracing
- // TODO implement a garbage collector
- void* alloc_mem (int size) {
- void *ret = calloc(size, 4);
- if (!ret)
- _error("couldn't allocate memory");
- return ret;
- }
- void free_mem (void* pointer) {
- free(pointer);
- }
- // duplicating and freeing:
- Atom* duplicate_atom (Atom* at) {
- if (!at) return NULL;
- if (is_simple(at)) {
- if (at->type == SYMB)
- return create_symbol(duplicate_symbol(at->symb));
- return create_int(at->num);
- }
- Atom *na = create_atom(at->type);
- na->list = duplicate_list(at->list);
- return na;
- }
- List* duplicate_list (List* li) {
- if (!li) return NULL;
- List *nli = cons(NULL, NULL);
- List *np = nli;
- while (li) {
- if (li->head) np->head = duplicate_atom(li->head);
- if (li->tail) {
- np->tail = cons(NULL, NULL);
- np = np->tail;
- }
- li = li->tail;
- }
- return nli;
- }
- Table* duplicate_table (Table* ta) {
- if (!ta) return (Table*)_warning("DUPLICATE_TABLE" DUPLICATE_NULL);
- Table *nt = (Table*)ALLOC(sizeof(Table));
- Table *ntp = nt;
- while (ta) {
- ntp->key = duplicate_symbol(ta->key);
- ntp->value = duplicate_atom(ta->value);
- ntp->next = NULL;
- if (ta->next) {
- ntp->next = (Table*)ALLOC(sizeof(Table));
- ntp = ntp->next;
- }
- ta = ta->next;
- }
- return nt;
- }
- int* duplicate_symbol (int* symb) {
- if (symb == NULL)
- return NULL;
- int *ns = (int*)ALLOC(symb[0]+1);
- for (int a = 0; a <= symb[0]; a ++) {
- ns[a] = symb[a];
- }
- return ns;
- }
- void free_atom (Atom* at) {
- if (!at)
- return;
- if (is_simple(at)) {
- if (at->type == SYMB) FREE(at->symb);
- } else {
- free_list(at->list);
- }
- FREE(at);
- }
- void free_list (List* li) {
- if (!li) return;
- if (li->head) free_atom(li->head);
- if (li->tail)
- free_list(li->tail);
- FREE(li);
- }
- void free_table (Table* ta) {
- if (!ta) {
- _warning("FREE_TABLE" FREE_NULL);
- return;
- }
- FREE(ta->key);
- if (ta->value)
- free_atom(ta->value);
- if (ta->next)
- free_table(ta->next);
- FREE(ta);
- }
- // creating objects:
- List* cons (Atom* he, List* ta) {
- List *nl = (List*)ALLOC(sizeof(List));
- nl->head = he;
- nl->tail = ta;
- return nl;
- }
- Atom* create_atom (Type _type) {
- Atom *at = (Atom*)ALLOC(sizeof(Atom));
- at->type = _type;
- return at;
- }
- Atom* create_int (int in) {
- Atom *at = create_atom(NUM);
- at->num = in;
- return at;
- }
- Atom* create_symbol (int* symb) {
- Atom *at = create_atom(SYMB);
- at->symb = symb;
- return at;
- }
- Atom* create_list (List* li) {
- if (li == NULL)
- return NULL;
- Atom *at = create_atom(LIST);
- at->list = li;
- return at;
- }
- Atom* create_lambda (List* la) {
- if (la == NULL)
- return NULL;
- Atom *at = create_atom(LAMBDA);
- at->list = la;
- return at;
- }
|