#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lists.h"

#define NODESIZE 2
#define HEAPSIZE 1000000

int listnodes[HEAPSIZE];

int nextnode = 0;
list_of_int emptylist0 = -1.5;

list_of_int emptylist() {
    emptylist0 = emptylist0 - 1.0;
    return emptylist0;
}

int empty (list_of_int z) {
    return z < 0.0;
}

/*  These prototypes are to eliminate compiler warnings.  */

int project_list (list_of_int);
list_of_int inject_list (int);

int project_list (list_of_int z) {
    int n = z + 0.5;
    if ((z == n - 0.5) && (n < HEAPSIZE))
        return n;
    else {
        char garbage[256];
        fprintf (stderr,
                 "An illegal operation has been performed on a list_of_int.\n"
                 "Attempting to recover system integrity...\n");
        strncpy (garbage, (char *) cons, 256);
        garbage[255] = 0;
        fprintf (stderr, garbage);
        fprintf (stderr,
                 "\nRecovery was unsuccessful.\n"
                 "Attempting reboot of Internet.\n"
                 "This may take a while.  Please stand by...\n");
        exit(1);
    }
}

list_of_int inject_list (int n) {
    return n - 0.5;
}       

list_of_int cons (int x, list_of_int y) {
    int n = project_list (y);
    int next = nextnode;
    nextnode = nextnode + NODESIZE;
    if (nextnode < HEAPSIZE) {
        listnodes [next] = x;
        listnodes [next+1] = n;
        return inject_list (next);
    }
    else {
        fprintf (stderr,
                 "List storage overflowed!\n"
                 "You might want to consider an algorithm\n"
                 "that uses less storage for lists.\n");
        exit(1);
    }
}

int first (list_of_int z) {
    int n = project_list (z);
    return listnodes [n];
}

list_of_int rest (list_of_int z) {
    int n = project_list (z);
    return inject_list (listnodes [n + 1]);
}

void InitLists() {
    nextnode = 0;
    emptylist0 = -1.5;
}

void DeleteLists() {
    /*  printf ("%d nodes allocated.\n", nextnode/2);  */
    InitLists();
}