
// Example S-exprs
// https://www.hboehm.info/gc/04tutorial.pdf
/**/
/*typedef union se*/
/*{*/
/*  struct cons * cp;*/
/*  mpz_t i;*/
/*} sexpr;*/
/**/
/*struct cons*/
/*{*/
/*  union se head;*/
/*  union se tail;*/
/*};*/
/**/
/*#define car(s) (s).cp->head*/
/*#define cdr(s) (s).cp->tail*/
/*#define from_i(z) ({sexpr tmp; tmp.i=z; tmp;})*/
/*#define to_i(s) (s).i*/
/**/
/*sexpr cons(sexpr a, sexpr b) {*/
/*    sexpr tmp = {GC_MALLOC(sizeof(struct cons))};*/
/*    car(tmp) = a; cdr(tmp) = b;*/
/*    return (tmp);*/
/*};*/



/*sexpr new_int(void) {*/
/*  sexpr node = {GC_MALLOC(sizeof(struct cons))};*/
/*  mpz_init(node.i);*/
/*  GC_register_finalizer(node.i, my_callback, NULL, NULL, NULL);*/
/*  return (node);*/
/*}*/


typedef struct list_node* JoyList;



	/*sexpr i = new_int();*/
	/*mpz_add(i.i, pi, pi);*/
	/*gmp_printf ("%Zd\n", i.i);*/
	/*return to_i(car(cons(from_i(0),from_i(1))));*/

	/*gmp_printf("%Zd = %Zx\n", pi, pi);*/
	/*mpz_mul(pi, pi, pi);*/
	/*gmp_printf("%Zd = %Zx\n", pi, pi);*/
'








/*=======================================================*/
struct list_node*
text_to_expression(char *text)
{
	char *rest;
	ptrdiff_t diff;
	struct list_node *thing;
	struct list_node *result;
	struct list_node *tail = NULL;
	struct list_node *stack[128];
	int s = 0; /* stack pointer */

	/* NULL string input? */
	if (NULL == text) {
		return EMPTY_LIST;
	}

	text = trim_leading_blanks(text);

	/* All blanks? */
	if (NULL == text) {
		return EMPTY_LIST;
	}

	/* Look for blanks or brackets. */
	rest = strpbrk(text, " []");
	/*
	rest now points to a space or '[' or ']' after a term,
	-or- it is NULL if the rest of the string is a single term
	with no spaces nor brackets.  If that's the case then we're
	done, and we can just return a list with one symbol in it.
	*/
	if (NULL == rest) {
		return make_symbol_node(text, strlen(text));
	}

	/* How many chars have we got? */
	diff = rest - text;

	if (diff) {
		thing = make_symbol_node(text, diff);
		if (tail) {
			tail->tail = thing;
		} else {
			/* There is no head now, so this must be the first
			   result, the head that we will eventually return. */
			result = thing;
		}
		tail = thing;

	} else if ('[' == rest[0]) {
		rest++;
		/* We need to parse a sub-list. */
		if (tail) {
			/* We have already parsed some terms, set them aside. */
			stack[s++] = tail;
			stack[s++] = result;
			tail = (struct list_node *)NULL;
		} else {
			/*
			This is going to be our first term when we're done parsing it.
			Do nothing, empty stack will signal it.
			*/
			
		}
	} else if (']' == rest[0]) {
		rest++;
		if (s) {
			/* We have a tail on the stack. */
			thing = result;
			result = stack[--s];
			tail = stack[--s];
			tail->tail = thing;
		} else {
			/* This list must have been the first thing in the expr. */
			printf("wtf");
			exit(1);
		}
	} else {
		
	}

	result = make_symbol_node(text, diff);
	
	/*
	This is the head of the list we are eventually going to return,
	so we assign it to the result
	We are going to be adding things to the tail of this list, so
	we'll need to keep track of that
	*/
	tail = result;
	
	/*
	Now we want to 
	*/
	while (NULL != rest) {
	

			if (head) {
				head->tail = current_list_node;
			} else {
				/* There is no head now, so this must be the first
				   result, the head that we will eventually return. */
				result = current_list_node;
			}
			head = current_list_node;
		}

		/* The next char is a space or '[' or ']'. */
		if ('[' == rest[0]) {
			if (head) {
				stack[s++] = head;
				head = (struct list_node *)NULL;
			}
			/*printf("%c\n", rest[0]);*/
		}

		if (']' == rest[0]) {
			current_list_node = make_list_node(stack[s--]);
			if (head) {
				head->tail = current_list_node;
			} else {
				/* There is no head now, so this must be the first
				   result, the head that we will eventually return. */
				result = current_list_node;
			}
			head = current_list_node;
			/*printf("%c\n", rest[0]);*/
		}

		text = trim_leading_blanks(++rest);

		/* calling strpbrk on NULL caused segfault! */
		rest = (NULL != text) ? strpbrk(text, " []") : text;
	}
	if (text) {
		current_list_node = make_symbol_node(text, strlen(text));
		if (head) {
			head->tail = current_list_node;
		} else {
			result = current_list_node;
		}
	}
	return result;
}
'

	/*mpz_t pi;*/
	/*char *text = (char *)TEXT;*/
	/*mpz_init_set_str(pi, "3141592653589793238462643383279502884", 10);*/
	/*mpz_init_set_str(pi, "25d0c79fe247f31777d922627a74624", 16);*/
	/*GC_register_finalizer(pi, my_callback, NULL, NULL, NULL);*/

	/*el = push_integer_from_str("3141592653589793238462643383279502884", 0);*/
	/*el->tail = text_to_expression(text);*/
	/*el = text_to_expression(text);*/
	/*print_list(el);*/
	/*printf("\n");*/

  
  /*const char *TEXT = " 23 [dup   *] i hi there  fr  [[]  ie]nd  []    23      ";*/
/*const char *TEXT = " 23 33 []     ";*/
const char *TEXT = "ok [wow] [23 45][1[2]3]simple terms already work eh?   ";
