#include "./funk.h"

void Take(Let dest[], const char * src){
	Let i = 0;
	while(src[i]!=0){
		dest[i] = src[i];
		i++;
	}
	dest[i] = 0;
}

void Permute(Let lst[]){
	Let i=0;
	Let buffer = 0;
	while(lst[i] != 0){
		buffer = buffer ^ lst[i];
		lst[i] = buffer ^ lst[i];
		buffer = buffer ^ lst[i];
		i++;
	}
	if (lst[i+1] == 0){
		lst[i] = buffer;
		lst[i+1] = 0;
	}
}

void Range(Let lst[], Let end){
	for (Let i=0;i<end;i++){
		lst[i] = i+1;
	}
}


/* */

void Transform(Let current[], Funk funk){
	while(First(current)!=0){
		current[0] = funk(First(current),Rest(current));
		current = Rest(current);
	}
}

void Predicate(Let lst[], Funk funk){
	Let i=0, j=0;
	while(lst[i]!=0){
		if(i!=j){
			lst[j] = lst[i];
		}
		if(funk(lst[i], &lst[i+1])!=0){
			j++;
		}
		i++;
	}
 	while(j<i){
		lst[--i]=0;
	}
}

void Aggregate(Let lst[], Funk funk){
	Let i=0;
	Let acc=0;
	while(lst[i] != 0){
		acc = funk(acc, &lst[i]);
		i++; 
	}
	lst[0] = acc;
}

void Enumerate(Let lst[], Funk funk){
	Let i=0;
	while(lst[i]!=0){
		lst[i] = funk(i,lst);
		i++;
	}
}

void Generate(Let lst[], Funk funk){
	Let i=0;
	while(lst[i] == 0){
		lst[i] = funk(i, lst);
		if (lst[i] == 0) {
			break;
		}
		i++;
	}
}

void Sort(Let lst[],Funk funk){
	Let i=0;while(lst[i] != 0){
	Let j = i+1;while(lst[j] != 0){
	lst[i] = funk(lst[i],&lst[j]);
	j++;}i++;}
}


/*  */
void Do(Routine now,Let lst[]){
	struct Continuation co = { now, lst };
	while(co.routine != 0){
		Routine fn = co.routine;
		//co.routine = 0;
		fn(&co);
	}
}
/*  */
Let Cell(Let w, Let col, Let row){
	return (row*w)+col;
}

Let Cerealize(Let val){
	return val;
}

Let Decerealize(Let val){
	return val;
}
